/**
 * Returns true only if str is a valid url
 * @param {string} str
 */
export function isURL (str) {
  try {
    // eslint-disable-next-line no-new
    new URL(str)
  } catch (e) {
    return false
  }
  return true
}

export function stripProtocol (url) {
  return url.replace(/(^\w+:|^)\/\//, '')
}

export function stripWWW (url) {
  return url.replace(/^www\./, '')
}

export function startsWithProtocol (str) {
  return str.match(/(^\w+:|^)\/\//) !== null
}

export function startsWithWWW (str) {
  return str.match(/^www\./, '') !== null
}

/**
 * Based on https://github.com/1995eaton/chromium-vim/blob/aec10cf47943b4674a5bc92c46d3c3c138d3cba3/content_scripts/utils.js#L51
 */
export function searchURL (
  query,
  queryURLTemplate = 'https://www.google.com/search?q='
) {
  return isLikeURL(query)
    ? (!/^[a-zA-Z-]+:/.test(query) ? 'https://' : '') + query
    : searchEngineQueryURL(query, queryURLTemplate)
}

/**
 * Based on https://github.com/1995eaton/chromium-vim/blob/aec10cf47943b4674a5bc92c46d3c3c138d3cba3/content_scripts/utils.js#L45
 */
export function searchEngineQueryURL (query, queryURLTemplate) {
  const encodedSearchQuery = encodeURIComponent(query)
  const i = queryURLTemplate.lastIndexOf('%s')
  return i < 0
    ? `${queryURLTemplate}${encodedSearchQuery}`
    : `${queryURLTemplate.slice(
        0,
        i
      )}${encodedSearchQuery}${queryURLTemplate.slice(i + 2)}`
}

/**
 * Returns true if the text is a valid URL (including protocol, e.g. https://hello)
 * or probably corresponds to a valid URL (e.g. google.com)
 * Based on https://github.com/1995eaton/chromium-vim/blob/aec10cf47943b4674a5bc92c46d3c3c138d3cba3/content_scripts/utils.js#L59
 */
export function isLikeURL (url) {
  url = url.trim()
  if (url.indexOf(' ') !== -1) {
    return false
  }
  if (url.search(/^(about|file):[^:]/) !== -1) {
    return true
  }
  const protocol = (url.match(/^([a-zA-Z-]+:)[^:]/) || [''])[0].slice(0, -1)
  const protocolMatch = isProtocol(protocol)
  if (protocolMatch) {
    url = url.replace(/^[a-zA-Z-]+:\/*/, '')
  }
  const hasPath = /.*[a-zA-Z].*\//.test(url)
  url = url.replace(/(:[0-9]+)?([#/].*|$)/g, '').split('.')
  if (protocolMatch && /^[a-zA-Z0-9@!]+$/.test(url)) {
    return true
  }
  if (protocol && !protocolMatch && protocol !== 'localhost:') {
    return false
  }
  // IP addresses
  const isIP = url.every(e => /^[0-9]+$/.test(e) && +e >= 0 && +e < 256)
  if ((isIP && !protocol && url.length === 4) || (isIP && protocolMatch)) {
    return true
  }
  return (
    (url.every(e => /^[a-z0-9-]+$/i.test(e)) &&
      url.length > 1 && isTLD(url[url.length - 1])) ||
    (url.length === 1 && url[0] === 'localhost') ||
    hasPath
  )
}

const knownTLDs = [
  'abogado',
  'ac',
  'academy',
  'accountants',
  'active',
  'actor',
  'ad',
  'adult',
  'ae',
  'aero',
  'af',
  'ag',
  'agency',
  'ai',
  'airforce',
  'al',
  'allfinanz',
  'alsace',
  'am',
  'amsterdam',
  'an',
  'android',
  'ao',
  'aq',
  'aquarelle',
  'ar',
  'archi',
  'army',
  'arpa',
  'as',
  'asia',
  'associates',
  'at',
  'attorney',
  'au',
  'auction',
  'audio',
  'autos',
  'aw',
  'ax',
  'axa',
  'az',
  'ba',
  'band',
  'bank',
  'bar',
  'barclaycard',
  'barclays',
  'bargains',
  'bayern',
  'bb',
  'bd',
  'be',
  'beer',
  'berlin',
  'best',
  'bf',
  'bg',
  'bh',
  'bi',
  'bid',
  'bike',
  'bio',
  'biz',
  'bj',
  'black',
  'blackfriday',
  'bloomberg',
  'blue',
  'bm',
  'bmw',
  'bn',
  'bnpparibas',
  'bo',
  'boo',
  'boutique',
  'br',
  'brussels',
  'bs',
  'bt',
  'budapest',
  'build',
  'builders',
  'business',
  'buzz',
  'bv',
  'bw',
  'by',
  'bz',
  'bzh',
  'ca',
  'cab',
  'cal',
  'camera',
  'camp',
  'cancerresearch',
  'capetown',
  'capital',
  'caravan',
  'cards',
  'care',
  'career',
  'careers',
  'cartier',
  'casa',
  'cash',
  'cat',
  'catering',
  'cc',
  'cd',
  'center',
  'ceo',
  'cern',
  'cf',
  'cg',
  'ch',
  'channel',
  'cheap',
  'christmas',
  'chrome',
  'church',
  'ci',
  'citic',
  'city',
  'ck',
  'cl',
  'claims',
  'cleaning',
  'click',
  'clinic',
  'clothing',
  'club',
  'cm',
  'cn',
  'co',
  'coach',
  'codes',
  'coffee',
  'college',
  'cologne',
  'com',
  'community',
  'company',
  'computer',
  'condos',
  'construction',
  'consulting',
  'contractors',
  'cooking',
  'cool',
  'coop',
  'country',
  'cr',
  'credit',
  'creditcard',
  'cricket',
  'crs',
  'cruises',
  'cu',
  'cuisinella',
  'cv',
  'cw',
  'cx',
  'cy',
  'cymru',
  'cz',
  'dabur',
  'dad',
  'dance',
  'dating',
  'day',
  'dclk',
  'de',
  'deals',
  'degree',
  'delivery',
  'democrat',
  'dental',
  'dentist',
  'desi',
  'design',
  'dev',
  'diamonds',
  'diet',
  'digital',
  'direct',
  'directory',
  'discount',
  'dj',
  'dk',
  'dm',
  'dnp',
  'do',
  'docs',
  'domains',
  'doosan',
  'durban',
  'dvag',
  'dz',
  'eat',
  'ec',
  'edu',
  'education',
  'ee',
  'eg',
  'email',
  'emerck',
  'energy',
  'engineer',
  'engineering',
  'enterprises',
  'equipment',
  'er',
  'es',
  'esq',
  'estate',
  'et',
  'eu',
  'eurovision',
  'eus',
  'events',
  'everbank',
  'exchange',
  'expert',
  'exposed',
  'fail',
  'farm',
  'fashion',
  'feedback',
  'fi',
  'finance',
  'financial',
  'firmdale',
  'fish',
  'fishing',
  'fit',
  'fitness',
  'fj',
  'fk',
  'flights',
  'florist',
  'flowers',
  'flsmidth',
  'fly',
  'fm',
  'fo',
  'foo',
  'forsale',
  'foundation',
  'fr',
  'frl',
  'frogans',
  'fund',
  'furniture',
  'futbol',
  'ga',
  'gal',
  'gallery',
  'garden',
  'gb',
  'gbiz',
  'gd',
  'ge',
  'gent',
  'gf',
  'gg',
  'ggee',
  'gh',
  'gi',
  'gift',
  'gifts',
  'gives',
  'gl',
  'glass',
  'gle',
  'global',
  'globo',
  'gm',
  'gmail',
  'gmo',
  'gmx',
  'gn',
  'goog',
  'google',
  'gop',
  'gov',
  'gp',
  'gq',
  'gr',
  'graphics',
  'gratis',
  'green',
  'gripe',
  'gs',
  'gt',
  'gu',
  'guide',
  'guitars',
  'guru',
  'gw',
  'gy',
  'hamburg',
  'hangout',
  'haus',
  'healthcare',
  'help',
  'here',
  'hermes',
  'hiphop',
  'hiv',
  'hk',
  'hm',
  'hn',
  'holdings',
  'holiday',
  'homes',
  'horse',
  'host',
  'hosting',
  'house',
  'how',
  'hr',
  'ht',
  'hu',
  'ibm',
  'id',
  'ie',
  'ifm',
  'il',
  'im',
  'immo',
  'immobilien',
  'in',
  'industries',
  'info',
  'ing',
  'ink',
  'institute',
  'insure',
  'int',
  'international',
  'investments',
  'io',
  'iq',
  'ir',
  'irish',
  'is',
  'it',
  'iwc',
  'jcb',
  'je',
  'jetzt',
  'jm',
  'jo',
  'jobs',
  'joburg',
  'jp',
  'juegos',
  'kaufen',
  'kddi',
  'ke',
  'kg',
  'kh',
  'ki',
  'kim',
  'kitchen',
  'kiwi',
  'km',
  'kn',
  'koeln',
  'kp',
  'kr',
  'krd',
  'kred',
  'kw',
  'ky',
  'kyoto',
  'kz',
  'la',
  'lacaixa',
  'land',
  'lat',
  'latrobe',
  'lawyer',
  'lb',
  'lc',
  'lds',
  'lease',
  'legal',
  'lgbt',
  'li',
  'lidl',
  'life',
  'lighting',
  'limited',
  'limo',
  'link',
  'lk',
  'loans',
  'london',
  'lotte',
  'lotto',
  'lr',
  'ls',
  'lt',
  'ltda',
  'lu',
  'luxe',
  'luxury',
  'lv',
  'ly',
  'ma',
  'madrid',
  'maison',
  'management',
  'mango',
  'market',
  'marketing',
  'marriott',
  'mc',
  'md',
  'me',
  'media',
  'meet',
  'melbourne',
  'meme',
  'memorial',
  'menu',
  'mg',
  'mh',
  'miami',
  'mil',
  'mini',
  'mk',
  'ml',
  'mm',
  'mn',
  'mo',
  'mobi',
  'moda',
  'moe',
  'monash',
  'money',
  'mormon',
  'mortgage',
  'moscow',
  'motorcycles',
  'mov',
  'mp',
  'mq',
  'mr',
  'ms',
  'mt',
  'mu',
  'museum',
  'mv',
  'mw',
  'mx',
  'my',
  'mz',
  'na',
  'nagoya',
  'name',
  'navy',
  'nc',
  'ne',
  'net',
  'network',
  'neustar',
  'new',
  'nexus',
  'nf',
  'ng',
  'ngo',
  'nhk',
  'ni',
  'ninja',
  'nl',
  'no',
  'np',
  'nr',
  'nra',
  'nrw',
  'nu',
  'nyc',
  'nz',
  'okinawa',
  'om',
  'one',
  'ong',
  'onl',
  'ooo',
  'org',
  'organic',
  'osaka',
  'otsuka',
  'ovh',
  'pa',
  'paris',
  'partners',
  'parts',
  'party',
  'pe',
  'pf',
  'pg',
  'ph',
  'pharmacy',
  'photo',
  'photography',
  'photos',
  'physio',
  'pics',
  'pictures',
  'pink',
  'pizza',
  'pk',
  'pl',
  'place',
  'plumbing',
  'pm',
  'pn',
  'pohl',
  'poker',
  'porn',
  'post',
  'pr',
  'praxi',
  'press',
  'pro',
  'prod',
  'productions',
  'prof',
  'properties',
  'property',
  'ps',
  'pt',
  'pub',
  'pw',
  'py',
  'qa',
  'qpon',
  'quebec',
  're',
  'realtor',
  'recipes',
  'red',
  'rehab',
  'reise',
  'reisen',
  'reit',
  'ren',
  'rentals',
  'repair',
  'report',
  'republican',
  'rest',
  'restaurant',
  'reviews',
  'rich',
  'rio',
  'rip',
  'ro',
  'rocks',
  'rodeo',
  'rs',
  'rsvp',
  'ru',
  'ruhr',
  'rw',
  'ryukyu',
  'sa',
  'saarland',
  'sale',
  'samsung',
  'sarl',
  'sb',
  'sc',
  'sca',
  'scb',
  'schmidt',
  'schule',
  'schwarz',
  'science',
  'scot',
  'sd',
  'se',
  'services',
  'sew',
  'sexy',
  'sg',
  'sh',
  'shiksha',
  'shoes',
  'shriram',
  'si',
  'singles',
  'sj',
  'sk',
  'sky',
  'sl',
  'sm',
  'sn',
  'so',
  'social',
  'software',
  'sohu',
  'solar',
  'solutions',
  'soy',
  'space',
  'spiegel',
  'sr',
  'st',
  'su',
  'supplies',
  'supply',
  'support',
  'surf',
  'surgery',
  'suzuki',
  'sv',
  'sx',
  'sy',
  'sydney',
  'systems',
  'sz',
  'taipei',
  'tatar',
  'tattoo',
  'tax',
  'tc',
  'td',
  'technology',
  'tel',
  'temasek',
  'tf',
  'tg',
  'th',
  'tienda',
  'tips',
  'tires',
  'tirol',
  'tj',
  'tk',
  'tl',
  'tm',
  'tn',
  'to',
  'today',
  'tokyo',
  'tools',
  'top',
  'town',
  'toys',
  'tp',
  'tr',
  'trade',
  'training',
  'travel',
  'trust',
  'tt',
  'tui',
  'tv',
  'tw',
  'tz',
  'ua',
  'ug',
  'uk',
  'university',
  'uno',
  'uol',
  'us',
  'uy',
  'uz',
  'va',
  'vacations',
  'vc',
  've',
  'vegas',
  'ventures',
  'versicherung',
  'vet',
  'vg',
  'vi',
  'viajes',
  'video',
  'villas',
  'vision',
  'vlaanderen',
  'vn',
  'vodka',
  'vote',
  'voting',
  'voto',
  'voyage',
  'vu',
  'wales',
  'wang',
  'watch',
  'webcam',
  'website',
  'wed',
  'wedding',
  'wf',
  'whoswho',
  'wien',
  'wiki',
  'williamhill',
  'wme',
  'work',
  'works',
  'world',
  'ws',
  'wtc',
  'wtf',
  'xn--1qqw23a',
  'xn--3bst00m',
  'xn--3ds443g',
  'xn--3e0b707e',
  'xn--45brj9c',
  'xn--45q11c',
  'xn--4gbrim',
  'xn--55qw42g',
  'xn--55qx5d',
  'xn--6frz82g',
  'xn--6qq986b3xl',
  'xn--80adxhks',
  'xn--80ao21a',
  'xn--80asehdb',
  'xn--80aswg',
  'xn--90a3ac',
  'xn--b4w605ferd',
  'xn--c1avg',
  'xn--cg4bki',
  'xn--clchc0ea0b2g2a9gcd',
  'xn--czr694b',
  'xn--czrs0t',
  'xn--czru2d',
  'xn--d1acj3b',
  'xn--d1alf',
  'xn--fiq228c5hs',
  'xn--fiq64b',
  'xn--fiqs8s',
  'xn--fiqz9s',
  'xn--flw351e',
  'xn--fpcrj9c3d',
  'xn--fzc2c9e2c',
  'xn--gecrj9c',
  'xn--h2brj9c',
  'xn--hxt814e',
  'xn--i1b6b1a6a2e',
  'xn--io0a7i',
  'xn--j1amh',
  'xn--j6w193g',
  'xn--kprw13d',
  'xn--kpry57d',
  'xn--kput3i',
  'xn--l1acc',
  'xn--lgbbat1ad8j',
  'xn--mgb9awbf',
  'xn--mgba3a4f16a',
  'xn--mgbaam7a8h',
  'xn--mgbab2bd',
  'xn--mgbayh7gpa',
  'xn--mgbbh1a71e',
  'xn--mgbc0a9azcg',
  'xn--mgberp4a5d4ar',
  'xn--mgbx4cd0ab',
  'xn--ngbc5azd',
  'xn--node',
  'xn--nqv7f',
  'xn--nqv7fs00ema',
  'xn--o3cw4h',
  'xn--ogbpf8fl',
  'xn--p1acf',
  'xn--p1ai',
  'xn--pgbs0dh',
  'xn--q9jyb4c',
  'xn--qcka1pmc',
  'xn--rhqv96g',
  'xn--s9brj9c',
  'xn--ses554g',
  'xn--unup4y',
  'xn--vermgensberater-ctb',
  'xn--vermgensberatung-pwb',
  'xn--vhquv',
  'xn--wgbh1c',
  'xn--wgbl6a',
  'xn--xhq521b',
  'xn--xkc2al3hye2a',
  'xn--xkc2dl3a5ee0h',
  'xn--yfro4i67o',
  'xn--ygbi2ammx',
  'xn--zfr164b',
  'xxx',
  'xyz',
  'yachts',
  'yandex',
  'ye',
  'yoga',
  'yokohama',
  'YouTube',
  'yt',
  'za',
  'zip',
  'zm',
  'zone',
  'zuerich',
  'zw'
]
/** Returns whether the provided text is a known TLD (top-level domain) */
export function isTLD (text) {
  return knownTLDs.indexOf(text) !== -1
}

const knownProtocols = [
  'http:',
  'https:',
  'file:',
  'ftp:',
  'chrome:',
  'chrome-extension:'
]
/** Returns whether the provided text is a known protocol */
export function isProtocol (text) {
  return knownProtocols.indexOf(text) !== -1
}
